Spring Security Note-17
Spring Security授权简介
Spring Security授权定义
我们所谓的菜单,按钮触发的对应的一个后台的URL,授权并不是看见与否,而是能否访问;
安全问题,涉及的是访问与否的问题;
在用户体验的情况下,会给出所谓的按钮和菜单,但是在没有权限访问的前提下,最终依然没有访问的能力,给出的是提示;
涉及的用户体验和安全,要求不同,给出的解决方案是不同,最终我们只需要将自定义开发权限模块和Spring Security对接即可;
举例
业务系统(普通用户)、内管系统(公司运营人员),对于这两个系统来说,授权是不同的;
在业务系统当中,只区分是否登录(浏览、操作)或区分简单的角色(普通、VIP),权限规则基本不变;
在内管系统当中,角色众多,权限复杂,权限规则随着体系和业务的发展不断变化;
在应用系统内部,需要两份数据,一份是系统配置信息(每个URL需要的权限),一份是用户权限信息(用户1有ABC权限),对于请求,将会对两份数据进行比对以获取访问请求;
应用
在BrowserSecurityConfig的authorizeRequests()已经进行URL的配置;
接下去对于角色的验证
1 | // 指定URL的角色 |
在MyUserDetailService
,可以指定返回用户的权限
1 | private SocialUserDetails buildUser(String username) { |
Spring Security源码解析
在这里的学习中,我们重点关注橙色的部分Filter Security Interceptor
,它最终决定你的请求是否能够通过,访问到REST API ;
如果不能访问,它会抛出异常,并且说明原因,由蓝色部分Exception Translation Filter
来处理;
Anonymous Authentication Filter
匿名认证过滤器,位于绿色过滤器链段最后一端;
Anonymous Authentication Filter
这个类十分简单,它主要关注你当前的SecurityContextHolder
是否有Authentication
,判断是否为空,实际上就是在判断,前面绿色过滤器链是否完成身份认证,如果为空,那么就会创建一个Authentication
;
这个由匿名认证过滤器创建的Authentication
,是匿名的principal
;
通过Anonymous Authentication Filter
,最终都会带有你的身份,去到Filter Security Interceptor
,由它来判断你的身份是否有对API的访问权限;
上面此图,是与Spring Security授权相关的类和接口;
最核心的三个类FilterSecurityInterceptor
& AccessDecisionManager
& AccessDecisionVoter
;
Filter Security Interceptor
整个控制授权的主入口;
Access Decision Manager
访问决定的管理者,它由一个抽象类Abstract Access Decision Manager
,和三个具体实现AffirmativeBased
& ConsensusBased
& UnanimouosBased
;
它在抽象类中,管理一组AccessDecisionVoter
;
Abstract Access Decision Manager
则会综合所有投票者的决定,给出一个最终的结果;
最终的结果,是有三套具体实现的逻辑;
AffirmativeBased
只要有一个通过就通过;
ConsensusBased
多数通过逻辑;
UnanimouosBased
只要有一个不通过就不通过;
默认Spring Security使用的是第一个逻辑,只要有一个通过就通过的逻辑;
Access Decision Voter
Voter是投票者,有一组投票者,每个投票者有不同的处理逻辑;
判断Authentication是否有某种角色,是否经过完全的身份认证;
每个投票者根据自己的逻辑,投出自己的一票,投出过还是不过;
Security Config
判断你的授权是否通过,需要两块数据的配置信息;
Security Config
会将系统配置信息读取出来,封装成一组Config Attribute
的对象;
这一组对象中,每一个Config Attribute
都会带有每一个URL所需要的权限;
Security Context Holder
当前用户的权限信息,会封装在Authentication
当中;
-
在进入到Access Decision Manager之前
,会封装三部分的信息Config Attribute
,Authentication
,请求信息
,成一个对象,进行授权认证的判断;
在Spring Security3.x以后,新产生的Wen Expression Voter
包办了所有的Voter的工作,在WEB的环境下,所有的Voter的工作由它承担;
权限表达式
Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应的权限,反之则无;
表达式 | 描述 |
---|---|
hasRole([role]) | 当前用户是否拥有指定角色。 |
hasAnyRole([role1,role2]) | 多个角色是一个以逗号进行分隔的字符串。如果当前用户拥有指定角色中的任意一个则返回true。 |
hasAuthority([auth]) | 等同于hasRole |
hasAnyAuthority([auth1,auth2]) | 等同于hasAnyRole |
Principle | 代表当前用户的principle对象 |
authentication | 直接从SecurityContext获取的当前Authentication对象 |
permitAll | 总是返回true,表示允许所有的 |
denyAll | 总是返回false,表示拒绝所有的 |
isAnonymous() | 当前用户是否是一个匿名用户 |
isRememberMe() | 表示当前用户是否是通过Remember-Me自动登录的 |
isAuthenticated() | 表示当前用户是否已经登录认证成功了。 |
isFullyAuthenticated() | 如果当前用户既不是一个匿名用户,同时又不是通过Remember-Me自动登录的,则返回true。 |
-
多权限表达式
-
实现
配置提供者
1 | public interface AuthorizeConfigProvider { |
具体实现配置提供者
1 |
|
配置管理器
1 | public interface AuthorizeConfigManager { |
具体实现配置管理器
1 |
|
修改浏览器安全配置
1 |
|
修改APP资源管理器安全配置
1 |
|
基于数据库RBAC数据模型控制权限
在内管系统中,以满足角色众多,权限复杂,权限规则随着业务的发展不断变化的问题,我们需要将权限放入到数据库当中,以添加,修改,删除数据的方式满足需要;
通用RBAC数据模型
RBAC(Role-Based Access Control):有大约5张表组成,3张实体表,2张关系表,分别是:
用户表:存储用户信息,由业务人员维护;
角色表:存储角色信息,由业务人员维护;
资源表:存储资源信息,菜单,按钮及其URL等,由开发人员维护;
用户-角色关系表(n-n):存储用户和角色的对应关系,由业务人员维护;
角色-资源关系表(n-n):存储角色和资源的对应关系,由业务人员维护;
声明权限服务
1 |
|
1 |
|